import hashlib
import binascii

fd_file = "/home/luying/uefi_workspace/edk2/Build/EmulatorX64/DEBUG_GCC5/FV/FV_RECOVERY.fd"
fv_file = "/home/luying/uefi_workspace/edk2/Build/OvmfX64/DEBUG_GCC5/FV/DXEFV.Fv"
gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid = b'\x31\x4e\x5e\x7f\xb1\x81\xe5\x47\x9e\x21\x1e\x4b\x5b\xc2\xf6\x1d'

def calculate_file_hash(file_path, hash_algorithm="sha256", buffer_size=8192):
    hash_object = hashlib.new(hash_algorithm)

    with open(file_path, "rb") as file:
        while True:
            chunk = file.read(buffer_size)
            if not chunk:
                break
            hash_object.update(chunk)

    file_hash = hash_object.hexdigest()
    return file_hash


def insert_hash_value(hash_value):
    binary_hash = binascii.unhexlify(hash_value)
    with open(fd_file, 'rb+') as file:
        whole_data = file.read()    
        if gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid in whole_data:
            print("find gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid success!\n")
        cur_index = 0
        target_index = whole_data[cur_index:].index(gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid) + cur_index
        print(whole_data[target_index:target_index+16])
        file.seek(target_index+16)
        file.write(binary_hash)

if __name__ == '__main__':
    hash_value = calculate_file_hash(fv_file)
    print(f"The sha256 hash of DXEFV is: {hash_value}\n")
    insert_hash_value(hash_value)